package org.xs.big_event.service.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.xs.big_event.dao.user.BaseUser;
import org.xs.big_event.dao.ReponseData;
import org.xs.big_event.dao.user.UserRepository;
import org.xs.big_event.service.IUserService;
import org.xs.big_event.utils.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;


@Service
public class UserService  implements IUserService {
    private final UserRepository userRepository;
    private FileUpLoadService fileUpLoadService;
    private AilOssUtil ossUtil;
    //密码加密
    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    @Autowired
    public UserService(UserRepository userRepository,
                       FileUpLoadService fileUpLoadService,
                       AilOssUtil ossUtil) {
        this.userRepository = userRepository;
        this.fileUpLoadService = fileUpLoadService;
        this.ossUtil = ossUtil;
    }
    /**
     * 登录
     * @param username
     * @param password
     * 1. 检查用户是否存在
     * 2，验证密码
     * 4.生成token
     * 5.返回 token与用户名
     * @return R
     */
    @Override
    public R login(String username,String password){
        //1.检验用户名是否存在
        Optional<BaseUser> user=userRepository.findByUsername(username);
        //用户不存在
        if (user.isEmpty()){
            return R.error(ResponseEnum.USER_NOT_EXIST);
        }
        else {
            //2.验证密码
            BaseUser baseUser = (BaseUser)user.get();
            if (!this.passwordEncoder.matches(password,baseUser.getPassword())){
                return R.error(ResponseEnum.USERNAME_PASSWORD_ERROR);
            }
            //3.生成token
            JSONObject jsonObject = JSONUtil.createObj().putOnce("userId",user.get().getId());
            //将token存储到redis 中
            String tokentemp=TokenUtil.createToken(jsonObject);
            RedisUtil.addToken(user.get().getId(),tokentemp);
            ReponseData token = new ReponseData();
            token.setToken(tokentemp);
            token.setUsername(username);
            Map<String,String> next= Map.of("next","/home");
            token.setData(next);
            return R.ok(token);
        }
    }

    //注册业务逻辑
    /*
    1.检查用户名是否存在
    2.检查密码格式
    3.创建用户
    4.返回用户名与重定向的路径
     */
    @Override
    public R register(String username, String password) {
        //1.检查用户名是否存在
        Optional<BaseUser> user=userRepository.findByUsername(username);
        //用户名存在
        if (user.isPresent()){
            return R.error(ResponseEnum.USER_EXIST);
        }
        //2.检查密码格式
        //3.创建用户
        BaseUser baseUser = new BaseUser();
        baseUser.setUsername(username);
        baseUser.setPassword(passwordEncoder.encode(password));
        baseUser.setNickname(username);
        baseUser.setCreate_time(LocalDateTime.now());
        baseUser.setUpdate_time(LocalDateTime.now());
        userRepository.save(baseUser);
        Map data= Map.of(username,baseUser.getUsername(),"next","/user/login");
        return R.ok(data);
    }
    /*
    登出
      1.删除token
      2.返回成功
     */
    @Override
    public R logout(HttpServletRequest request) {
        String token= TokenUtil.getToken(request);
        //在redis删除token
        RedisUtil.removeToken(token);
        return R.ok();
    }

    /*
    获取用户信息
    1.获取token
    2.验证token
    3.返回用户信息
     */
    @Override
    public R info(HttpServletRequest request) {
        Integer userId= Integer.valueOf(ThreadLocatUtil.get());
        Optional<BaseUser> user=userRepository.findById(userId);
        Map<String, Object> data = new HashMap<>();
        data.put("username", user.get().getUsername());
        data.put("nickname", userRepository.findByNickname(userId));
        data.put("email", userRepository.findByEmail(userId));
        data.put("user_pic", userRepository.findByUserPic(userId));
        //返回用户信息
        return R.ok(data);
    }
    /**
     * 修改用户信息
     * @param user
     * @return
     */
    @Override
    @Transactional
    public R update(BaseUser user) {
        Integer userId= Integer.valueOf(ThreadLocatUtil.get());
//        Optional<BaseUser> user1=userRepository.findById(userId);
        userRepository.updateUser(
                user.getNickname(),
                user.getEmail(),
//                user.getUser_pic(),
                LocalDateTime.now(),
                userId);
        return R.ok();
    }
    /**
     * 修改用户头像
     * @param file
     * @return
     * 1.删除旧头像
     * 2.上传新头像
     * 3.返回新头像url
     */
    @Override
    @Transactional
    public R updateAvatar(MultipartFile file) {
        //判断文件是否为空
        if (file==null){
            return R.error(ResponseEnum.FILE_EMPTY);
        }
        //1.删除旧头像
        if (ossUtil.deleteAvatarFile()==false){
            return R.error(ResponseEnum.FILE_UPLOAD_ERROR);
        }
        //2.上传新头像
        Integer userId= Integer.valueOf(ThreadLocatUtil.get());
        R result = fileUpLoadService.upload(file);
        String avatarUrl= result.getData().toString();
        userRepository.updateAvater(
                avatarUrl,
                LocalDateTime.now(),
                userId);
        return R.ok(avatarUrl);
    }

    /*
    获取用户头像
      * @return url
     */

    @Override
    public R getAvatar() {
        Integer userId= Integer.valueOf(ThreadLocatUtil.get());
        String avatarUrl= userRepository.findByUserPic(userId);
        return R.ok(avatarUrl);
    }

    /**
     * 修改密码
     * 1.校验参数
     * 2.校验旧密码
     * 3.修改密码
     * 4.更新时间
     * 5.返回成功
     * @param params
     * @return
     */
    @Override
    @Transactional
    public R updatePassword(Map<String, String> params) {
        String oldPassword=params.get("oldPassword");
        String newPassword=params.get("newPassword");
        // 检查请求参数是否为空
        if (oldPassword == null || newPassword == null) {
            return R.error(ResponseEnum.USERNAME_PASSWORD_ERROR);
        }
        Integer userId= Integer.valueOf(ThreadLocatUtil.get());
        Optional<BaseUser> user=userRepository.findById(userId);
        BaseUser baseUser = user.get();
        if (!this.passwordEncoder.matches(oldPassword,baseUser.getPassword())){
            return R.error(ResponseEnum.USERNAME_PASSWORD_ERROR);
        }
        baseUser.setPassword(passwordEncoder.encode(newPassword));
        baseUser.setUpdate_time(LocalDateTime.now());
        userRepository.save(baseUser);
        return R.ok();
    }


}
